from django.db import models


# Create your models here.
# inverter_second_data (逆变器侧秒级数据)元素模型
class InverterSecondDataElement:
    def __init__(self, id=None, save_time=None, inverter_active_power=None, inverter_output_current=None,
                 inverter_output_voltage=None, inverter_output_freq=None, pv_active_power=None, pv_output_current=None,
                 pv_output_voltage=None, storage_active_power=None, storage_output_current=None,
                 storage_output_voltage=None, storage_soc=None, information=None):
        self.id = get_without_none(id)
        self.save_time = get_without_none(save_time)
        self.inverter_active_power = get_without_none(inverter_active_power)
        self.inverter_output_current = get_without_none(inverter_output_current)
        self.inverter_output_voltage = get_without_none(inverter_output_voltage)
        self.inverter_output_freq = get_without_none(inverter_output_freq)
        self.pv_active_power = get_without_none(pv_active_power)
        self.pv_output_current = get_without_none(pv_output_current)
        self.pv_output_voltage = get_without_none(pv_output_voltage)
        self.storage_active_power = get_without_none(storage_active_power)
        self.storage_output_current = get_without_none(storage_output_current)
        self.storage_output_voltage = get_without_none(storage_output_voltage)
        self.storage_soc = get_without_none(storage_soc)
        self.information = get_without_none(information)

    @staticmethod
    def validate_data(data_dict):
        """
        检查读取到的所有字段数据是否有效。
        :param data_dict: {字段名: 数据值} 的字典
        """
        for field, value in data_dict.items():
            if value is None:
                raise ValueError(f"未读到有效数据：字段 {field} 的值为空！")


# inverter_hourly_data (逆变器侧小时级数据)元素模型
class InverterHourlyDataElement:
    def __init__(self, id=None, save_time=None, pv_cumulative_energy=None, information=None):
        self.id = get_without_none(id)
        self.save_time = get_without_none(save_time)
        self.pv_cumulative_energy = get_without_none(pv_cumulative_energy)
        self.information = get_without_none(information)

    @staticmethod
    def validate_data(data_dict):
        """
        检查读取到的所有字段数据是否有效。
        :param data_dict: {字段名: 数据值} 的字典
        """
        for field, value in data_dict.items():
            if value is None:
                raise ValueError(f"未读到有效数据：字段 {field} 的值为空！")

# para_data  (仿真参数数据)元素模型
class ParaDataElement:
    def __init__(self,
                 id=None,
                 year=None,
                 region=None,
                 pv_carbon_factor=None,
                 grid_carbon_factor=None,
                 electricity_price=None,
                 information=None):
        self.id = get_without_none(id)
        self.year = get_without_none(year)
        self.region = get_without_none(region)
        self.pv_carbon_factor = get_without_none(pv_carbon_factor)
        self.grid_carbon_factor = get_without_none(grid_carbon_factor)
        self.electricity_price = get_without_none(electricity_price)
        self.information = get_without_none(information)


# 基站秒级数据属性
class BsSecondDataElement:
    def __init__(self, id=None, time=None, bs_id=None, cell_1_user_count=None, cell_2_user_count=None,
                 uplink_throughput=None, downlink_throughput=None):
        self.id = id
        self.time = time
        self.bs_id = bs_id
        self.cell_1_user_count = cell_1_user_count
        self.cell_2_user_count = cell_2_user_count
        self.uplink_throughput = uplink_throughput
        self.downlink_throughput = downlink_throughput

    @staticmethod
    def validate_data(data_dict):
        """
        检查读取到的所有字段数据是否有效。
        :param data_dict: {字段名: 数据值} 的字典
        """
        for field, value in data_dict.items():
            if value is None:
                raise ValueError(f"未读到有效数据：字段 {field} 的值为空！")


# 分钟级数据结构
class BsMinuteDataElement:
    def __init__(self, id=None, time=None, bs_id=None, transmit_power=None):
        self.id = id
        self.time = time
        self.bs_id = bs_id
        self.transmit_power = transmit_power

    @staticmethod
    def validate_data(data_dict):
        """
        检查读取到的所有字段数据是否有效。
        :param data_dict: {字段名: 数据值} 的字典
        """
        for field, value in data_dict.items():
            if value is None:
                raise ValueError(f"未读到有效数据：字段 {field} 的值为空！")


# 基站小时级数据模型
class BsHourlyDataElement:
    def __init__(self, id=None, time=None, bs_id=None, uplink_bandwidth=None, downlink_bandwidth=None,
                 sleep_status=None, sleep_period=None, rf_status=None, ru_power_status=None, ru_status=None):
        self.id = id
        self.time = time
        self.bs_id = bs_id
        self.uplink_bandwidth = uplink_bandwidth
        self.downlink_bandwidth = downlink_bandwidth
        self.sleep_status = sleep_status
        self.sleep_period = sleep_period
        self.rf_status = rf_status
        self.ru_power_status = ru_power_status
        self.ru_status = ru_status

    @staticmethod
    def validate_data(data_dict):
        """
        检查读取到的所有字段数据是否有效。
        :param data_dict: {字段名: 数据值} 的字典
        :raises ValueError: 如果某个字段值为空（None），则抛出异常。
        """
        for field, value in data_dict.items():
            if value is None:
                raise ValueError(f"未读到有效数据：字段 {field} 的值为空！")


import json


# None数据处理
def get_without_none(s, ret_type=None):
    try:
        if ret_type == 'str':
            ret = '' if s is None else str(s)
        elif ret_type == 'li':
            ret = [] if s is None else list(s)
        elif ret_type == 'dic':
            ret = {} if s is None else dict(s)
        elif ret_type == 'json_loads':
            ret = '' if s is None else json.loads(s)
        elif ret_type == 'json_dumps':
            ret = '' if s is None else json.dumps(s)
        elif ret_type == 'float':
            ret = 0 if s is None else float(s)
        else:
            ret = '' if s is None else s
    except:
        if ret_type == 'float':
            ret = 0
        else:
            ret = ''
    return ret

class BsSecondDataElement:
    def __init__(self, id=None, time=None, bs_id=None, cell_1_user_count=None, cell_2_user_count=None,
                 uplink_throughput=None, downlink_throughput=None):
        self.id = id
        self.time = time
        self.bs_id = bs_id
        self.cell_1_user_count = cell_1_user_count
        self.cell_2_user_count = cell_2_user_count
        self.uplink_throughput = uplink_throughput
        self.downlink_throughput = downlink_throughput

    @staticmethod
    def validate_data(data_dict):
        """
        检查读取到的所有字段数据是否有效。
        :param data_dict: {字段名: 数据值} 的字典
        """
        for field, value in data_dict.items():
            if value is None:
                raise ValueError(f"未读到有效数据：字段 {field} 的值为空！")


from django.db import models
from django.contrib.postgres.fields import ArrayField


class InverterSecondData(models.Model):
    """
    逆变器秒级数据表：用于记录逆变器、光伏板和储能设备的秒级实时数据。
    """
    id = models.AutoField(primary_key=True)
    save_time = models.DateTimeField(null=False, verbose_name='数据采集时间戳')
    inverter_active_power = models.FloatField(null=True, verbose_name='逆变器有功功率 (W)')
    inverter_output_current = models.FloatField(null=True, verbose_name='逆变器输出电流 (A)')
    inverter_output_voltage = models.FloatField(null=True, verbose_name='逆变器输出电压 (V)')
    inverter_output_freq = models.FloatField(null=True, verbose_name='逆变器输出频率 (Hz)')
    pv_active_power = models.FloatField(null=True, verbose_name='光伏板有功功率 (W)')
    pv_output_current = models.FloatField(null=True, verbose_name='光伏板输出电流 (A)')
    pv_output_voltage = models.FloatField(null=True, verbose_name='光伏板输出电压 (V)')
    storage_active_power = models.FloatField(null=True, verbose_name='储能有功功率 (W)')
    storage_output_current = models.FloatField(null=True, verbose_name='储能输出电流 (A)')
    storage_output_voltage = models.FloatField(null=True, verbose_name='储能输出电压 (V)')
    storage_soc = models.FloatField(null=True, verbose_name='储能荷电状态 (SOC, %)')
    information = models.TextField(null=True, verbose_name='元素备用信息，包含中文名称和单位说明（如：字段名(中文名, 单位)）')

    class Meta:
        db_table = 'inverter_second_data'
        verbose_name = '逆变器秒级数据表'
        verbose_name_plural = verbose_name


class InverterHourlyData(models.Model):
    """
    逆变器侧小时级数据表：用于记录逆变器侧每小时的累计发电量等信息。
    """
    id = models.AutoField(primary_key=True)
    save_time = models.DateTimeField(null=False, verbose_name='数据采集时间戳')
    pv_cumulative_energy = models.FloatField(null=False, verbose_name='光伏累计发电量 (kWh)')
    information = models.TextField(null=True, verbose_name='元素备用信息，包含中文名称和单位说明（如：字段名(中文名, 单位)）')

    class Meta:
        db_table = 'inverter_hourly_data'
        verbose_name = '逆变器侧小时级数据表'
        verbose_name_plural = verbose_name


class BsSecondData(models.Model):
    """
    基站数据表：用于记录基站的用户接入数量及吞吐量等信息。
    """
    id = models.AutoField(primary_key=True)
    time = models.DateTimeField(null=False, verbose_name='数据采集时间')
    bs_id = models.CharField(max_length=30, null=False, verbose_name='基站唯一编号')
    cell_1_user_count = models.IntegerField(null=False, verbose_name='小区1接入用户数')
    cell_2_user_count = models.IntegerField(null=False, verbose_name='小区2接入用户数')
    uplink_throughput = models.FloatField(null=False, verbose_name='基站上行吞吐量(Mbps)')
    downlink_throughput = models.FloatField(null=False, verbose_name='基站下行吞吐量(Mbps)')
    information = models.TextField(null=True, verbose_name='备注信息，包含字段中文名称和单位说明')

    class Meta:
        db_table = 'bs_second_data'
        verbose_name = '基站数据表'
        verbose_name_plural = verbose_name


class BsMinuteData(models.Model):
    """
    基站分钟级数据表
    """
    id = models.AutoField(primary_key=True)
    time = models.TimeField(null=True, verbose_name='数据采集时间')
    bs_id = models.CharField(max_length=255, null=True, verbose_name='基站唯一编号')
    transmit_power = models.FloatField(null=True, verbose_name='基站发射功率')
    information = models.TextField(null=True, verbose_name='备注信息')

    class Meta:
        db_table = 'bs_minute_data'
        verbose_name = '基站分钟级数据表'
        verbose_name_plural = verbose_name


class BsHourlyData(models.Model):
    """
    基站小时级数据表
    """
    id = models.AutoField(primary_key=True)
    time = models.TimeField(null=True, verbose_name='数据采集时间')
    bs_id = models.CharField(max_length=255, null=True, verbose_name='基站唯一编号')
    uplink_bandwidth = models.FloatField(null=True, verbose_name='基站上行带宽')
    downlink_bandwidth = models.FloatField(null=True, verbose_name='基站下行带宽')
    sleep_status = models.BooleanField(null=True, verbose_name='基站休眠状态')
    sleep_period = models.CharField(max_length=255, null=True, verbose_name='基站休眠时间段')
    rf_status = models.CharField(max_length=255, null=True, verbose_name='射频供电开关状态')
    ru_power_status = models.BooleanField(null=True, verbose_name='RF射频状态')
    ru_status = models.BooleanField(null=True, verbose_name='RU状态')
    information = models.TextField(null=True, verbose_name='备注信息')

    class Meta:
        db_table = 'bs_hourly_data'
        verbose_name = '基站小时级数据表'
        verbose_name_plural = verbose_name


class BsPowerSecondData(models.Model):
    """
    基站功率秒级数据表
    """
    id = models.AutoField(primary_key=True)
    time = models.TimeField(null=True, verbose_name='数据采集时间')
    bs_id = models.CharField(max_length=255, null=True, verbose_name='基站唯一编号')
    power = models.FloatField(null=True, verbose_name='基站当前功率')
    information = models.TextField(null=True, verbose_name='备注信息')

    class Meta:
        db_table = 'bs_power_second_data'
        verbose_name = '基站功率秒级数据表'
        verbose_name_plural = verbose_name


class VirtualScene(models.Model):
    """
    虚拟场景表: bs_identifier(基站序号); time(生成时间); bs_number(基站数); user_number(用户数);
    bs_location_generation_algorithm(基站位置随机生成算法); user_location_generation_algorithm(用户位置随机生成算法); information(备注信息);
    """
    bs_identifier = models.AutoField(primary_key=True)
    time = models.DateTimeField(null=True, verbose_name='生成时间')
    bs_number = models.IntegerField(null=True, verbose_name='基站数')
    user_number = models.IntegerField(null=True, verbose_name='用户数')
    transmit_power = models.IntegerField(null=True, verbose_name='发射功率')
    bandwidth = models.IntegerField(null=True, verbose_name='带宽')
    sleep_period = models.CharField(max_length=255, null=True, verbose_name='休眠时间段')
    rf_status = models.BooleanField(null=True, verbose_name='射频状态')
    bs_location_generation_algorithm = models.CharField(max_length=64, null=True, verbose_name='基站位置生成算法')
    user_location_generation_algorithm = models.CharField(max_length=64, null=True, verbose_name='用户位置生成算法')
    information = models.TextField(null=True, verbose_name='备注信息')

    class Meta:
        db_table = 'virtualscene'
        verbose_name = '虚拟场景表'
        verbose_name_plural = verbose_name


class SceneBsElement(models.Model):
    """
    场景中基站的固定信息表:bs_id(唯一识别); time(生成时间); bs_id_scene(同场景下的基站序号); type(基站类型);
    is_physical_bs(是否为实物基站); lon(经度(横坐标)); lat(维度(纵坐标); bs_identifier(归属场景id); information(元素备用信息);
    """
    bs_id = models.AutoField(primary_key=True)
    time = models.DateTimeField(null=True, verbose_name='生成时间')
    bs_id_scene = models.CharField(max_length=30, null=True, verbose_name='基站序号')
    type = models.CharField(max_length=64, null=True, verbose_name='基站类型')
    is_physical_bs = models.BooleanField(null=True, verbose_name='是否为实物基站')
    lon = models.FloatField(null=True, verbose_name='经度')
    lat = models.FloatField(null=True, verbose_name='纬度')
    bs_identifier = models.ForeignKey(VirtualScene, on_delete=models.DO_NOTHING, null=False, verbose_name='归属场景ID')
    information = models.TextField(null=True, verbose_name='备用信息')

    class Meta:
        db_table = 'scene_bs_element'
        verbose_name = '场景中基站的固定信息表'
        verbose_name_plural = verbose_name


class SceneUserElement(models.Model):
    """
    场景中用户的固定信息表:user_id(唯一识别); time(生成时间); user_id_scene(同场景下的用户序号); type(用户类型);
    is_physical_user(是否为实物用户); lon(经度(横坐标)); lat(维度（纵坐标)); bs_identifier(归属场景); information(元素备用信息);
    """
    user_id = models.AutoField(primary_key=True)
    time = models.DateTimeField(null=True, verbose_name='生成时间')
    user_id_scene = models.CharField(max_length=30, null=True, verbose_name='用户序号')
    type = models.CharField(max_length=64, null=True, verbose_name='用户类型')
    is_physical_user = models.BooleanField(null=True, verbose_name='是否为实物用户')
    lon = models.FloatField(null=True, verbose_name='经度')
    lat = models.FloatField(null=True, verbose_name='纬度')
    bs_identifier = models.ForeignKey(VirtualScene, on_delete=models.DO_NOTHING, null=False, verbose_name='归属场景')
    information = models.TextField(null=True, verbose_name='备用信息')

    class Meta:
        db_table = 'scene_user_element'
        verbose_name = '场景中用户的固定信息表'
        verbose_name_plural = verbose_name


class BsStatus(models.Model):
    """
    场景中的基站状态表:id(唯一识别); time(时间); bs_id(基站唯一序号); bs_identifier(归属场景id); information(元素备用信息);
    """
    id = models.AutoField(primary_key=True)
    time = models.DateTimeField(null=True, verbose_name='时间')
    bs_id = models.ForeignKey(SceneBsElement, on_delete=models.DO_NOTHING, null=False, verbose_name='基站唯一序号')
    bs_identifier = models.ForeignKey(VirtualScene, on_delete=models.DO_NOTHING, null=False, verbose_name='归属场景ID')
    information = models.TextField(null=True, verbose_name='备用信息')

    class Meta:
        db_table = 'bs_status'
        verbose_name = '场景中的基站状态表'
        verbose_name_plural = verbose_name


class UserStatus(models.Model):
    """
    场景中的用户状态表: id(唯一识别); time(时间); user_id(唯一的用户序号); qos_request(用户服务质量要求, Mbps);
    qos(用户服务质量, Mbps); bs_identifier(归属场景id); information(元素备用信息);
    """
    id = models.AutoField(primary_key=True)
    time = models.DateTimeField(null=True, verbose_name='时间')
    user_id = models.ForeignKey(SceneUserElement, on_delete=models.CASCADE, null=False, verbose_name='唯一的用户序号')
    qos_request = models.FloatField(null=True, verbose_name='用户服务质量要求(Mbps)')
    qos = models.FloatField(null=True, verbose_name='用户服务质量(Mbps)')
    bs_identifier = models.ForeignKey(VirtualScene, on_delete=models.CASCADE, null=False, verbose_name='归属场景ID')
    information = models.TextField(null=True, verbose_name='备用信息')

    class Meta:
        db_table = 'user_status'
        verbose_name = '场景中的用户状态表'
        verbose_name_plural = verbose_name


class ParaData(models.Model):
    """
    仿真参数数据表:id(自增主键);year(数据采集的年份);region(地区标识);pv_carbon_factor(光伏碳排放因子,kgCO2/kWh);
    grid_carbon_factor(市电碳排放因子,kgCO2/kWh);electricity_price(电价,元/kWh);information(元素备用信息);
    """
    id = models.AutoField(primary_key=True)
    year = models.IntegerField(null=True, verbose_name='数据采集的年份')
    region = models.CharField(max_length=50, null=True, verbose_name='地区标识')
    pv_carbon_factor = models.FloatField(null=True, verbose_name='光伏碳排放因子')
    grid_carbon_factor = models.FloatField(null=True, verbose_name='市电碳排放因子')
    electricity_price = models.FloatField(null=True, verbose_name='电价')
    information = models.TextField(null=True, verbose_name='元素备用信息')

    class Meta:
        db_table = 'para_data'
        verbose_name = '仿真参数数据表'
        verbose_name_plural = verbose_name